home *** CD-ROM | disk | FTP | other *** search
- #include "global.h"
- #include "clipbrd.h"
- #include "edit.h"
- #include "obj.h"
- #include "rsc.h"
- #include "set.h"
- #include "trash.h"
- #include "block.h"
-
-
- /* lokale Prototypen *******************************************************/
- LOCAL VOID block_demark (TEXTP t_ptr);
- LOCAL BOOLEAN tab_ok (LINEP a, BOOLEAN tab, WORD tabsize);
- LOCAL VOID block_setzen (TEXTP t_ptr);
- LOCAL BOOLEAN block_delete (TEXTP t_ptr, RINGPTR t);
- LOCAL BOOLEAN block_einsetzen(TEXTP t_ptr, RINGPTR t);
-
- /* lokale Variablen ********************************************************/
-
- LOCAL WORD undo_anf_x, undo_end_x;
- LOCAL LONG undo_anf_y, undo_end_y;
-
-
- VOID blk_mark_all(TEXTP t_ptr)
- {
- LINEP col;
-
- if (t_ptr->block)
- block_demark(t_ptr);
- col = FIRST(&t_ptr->text);
- t_ptr->x1 = 0;
- t_ptr->p1 = col;
- t_ptr->z1 = 0;
- col = LAST(&t_ptr->text);
- t_ptr->x2 = col->len;
- t_ptr->p2 = col;
- t_ptr->z2 = t_ptr->text.lines-1;
- t_ptr->block_dir = FALSE; /* Anfang und Ende nicht vertauscht */
- block_setzen(t_ptr);
- make_chg(t_ptr->link,BLK_CHANGE,0);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
- }
-
-
- VOID blk_mark_word(TEXTP t_ptr) /* Wort unter dem Cursor markieren */
- {
- WORD pos,len;
- UBYTE *str;
-
- pos = t_ptr->xpos;
- str = TEXT(t_ptr->cursor_line)+pos;
- len = t_ptr->cursor_line->len;
- while(pos>=0 && setin(t_ptr->loc_opt->wort_set,*str))
- {
- pos--;
- str--;
- }
- str++; pos++;
- t_ptr->xpos = pos;
- blk_mark(t_ptr, 0);
- while(pos<=len && setin(t_ptr->loc_opt->wort_set,*str))
- {
- pos++;
- str++;
- }
- t_ptr->xpos = pos;
- blk_mark(t_ptr, 1);
- restore_edit();
- }
-
-
- VOID get_blk_mark(TEXTP t_ptr, LONG *y, WORD *x)
- {
- if (t_ptr->block_dir)
- {
- *y = t_ptr->z2;
- *x = t_ptr->x2;
- }
- else
- {
- *y = t_ptr->z1;
- *x = t_ptr->x1;
- }
- }
-
- VOID blk_mark(TEXTP t_ptr, WORD marke)
- /* Blockstart und -ende setzen */
- /* marke : 0 und 1 */
- {
- if (marke==0) /* Anfang setzten */
- {
- blk_demark(t_ptr);
- t_ptr->p2 = t_ptr->p1 = t_ptr->cursor_line;
- t_ptr->z2 = t_ptr->z1 = t_ptr->ypos;
- t_ptr->x2 = t_ptr->x1 = t_ptr->xpos;
- t_ptr->block_dir = FALSE;
- }
- else /* Block aufziehen */
- {
- if (t_ptr->block_dir)
- {
- if (t_ptr->p1 == t_ptr->cursor_line && t_ptr->x1 == t_ptr->xpos)
- return; /* Keine Änderung */
- if (t_ptr->block)
- {
- block_demark(t_ptr);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
- }
- else
- {
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
- }
- t_ptr->p1 = t_ptr->cursor_line;
- t_ptr->x1 = t_ptr->xpos;
- t_ptr->z1 = t_ptr->ypos;
- }
- else
- {
- if (t_ptr->p2==t_ptr->cursor_line && t_ptr->x2==t_ptr->xpos)
- return; /* Keine Änderung */
- if (t_ptr->block)
- {
- block_demark(t_ptr);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
- }
- else
- {
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
- }
- t_ptr->p2 = t_ptr->cursor_line;
- t_ptr->x2 = t_ptr->xpos;
- t_ptr->z2 = t_ptr->ypos;
- }
- block_setzen(t_ptr);
- }
- }
-
-
- VOID blk_demark(TEXTP t_ptr)
- {
- if (t_ptr->block)
- {
- block_demark(t_ptr);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
- make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
- t_ptr->p1 = t_ptr->p2 = NULL;
- t_ptr->z1 = t_ptr->z2 = -1;
- }
- }
-
-
- VOID blk_copy(TEXTP t_ptr, BOOLEAN add)
- /* Kopiert Block aus einem Text auf das Clipbrd */
- {
- RING t;
-
- if (!t_ptr->block)
- return;
- if (!ist_mem_frei())
- return;
- block_copy(t_ptr,&t);
- if (add)
- clip_add_text(&t);
- else
- clip_takes_text(&t);
- }
-
- VOID line_copy(TEXTP t_ptr, BOOLEAN add)
- /* Kopiert aktuelle Zeile auf das Clipboard */
- {
- LINEP col = t_ptr->cursor_line;
- WORD old_x;
-
- old_x = t_ptr->xpos;
- t_ptr->xpos = 0;
- blk_mark(t_ptr,0);
- if (IS_LAST(col))
- {
- t_ptr->xpos = col->len;
- blk_mark(t_ptr,1);
- t_ptr->xpos = old_x;
- }
- else
- {
- NEXT(col);
- t_ptr->cursor_line = col;
- blk_mark(t_ptr,1);
- VORG(col);
- t_ptr->cursor_line = col;
- t_ptr->xpos = old_x;
- }
- blk_copy(t_ptr,add);
- blk_demark(t_ptr);
- }
-
- VOID blk_paste(TEXTP t_ptr, RINGP t)
- /* Setzt den Text t im Text an Cursorposition ein */
- /* Der Cursor steht anschlie₧end dahinter */
- /* Ist ein Block da, wird er gelöscht */
- {
- if (!ist_mem_frei())
- return;
- blk_delete(t_ptr);
- block_einsetzen(t_ptr, t);
- t_ptr->moved++;
- add_undo(BLK_PASTE);
- }
-
- VOID blk_delete(TEXTP t_ptr)
- {
- RING t;
-
- if(!t_ptr->block)
- return;
- if (!ist_mem_frei())
- return;
- if (!block_delete(t_ptr, &t))
- return;
- trash_takes_text(&t);
- t_ptr->moved++;
- add_undo(BLK_DEL);
- }
-
- VOID blk_cut(TEXTP t_ptr, BOOLEAN add)
- {
- RING t, t2;
-
- if (!t_ptr->block)
- return;
- if (!ist_mem_frei())
- return;
- if (!block_delete(t_ptr, &t))
- return;
- init_textring(&t2);
- if (doppeln(&t,&t2))
- {
- if (add)
- clip_add_text(&t2);
- else
- clip_takes_text(&t2);
- }
- undo_takes_text(&t);
- t_ptr->moved++;
- add_undo(BLK_CUT);
- }
-
- VOID blk_undo(TEXTP t_ptr, WORD undo)
- {
- RING t;
-
- if (!ist_mem_frei())
- return;
- if (undo==BLK_PASTE || undo==BLK_PASTE_TRASH)
- /* Block mu₧ wieder gelöscht werden */
- {
- blk_demark(t_ptr);
- t_ptr->p1 = get_line(&t_ptr->text,undo_anf_y);
- t_ptr->z1 = undo_anf_y;
- t_ptr->x1 = undo_anf_x;
- t_ptr->p2 = get_line(&t_ptr->text,undo_end_y);
- t_ptr->z2 = undo_end_y;
- t_ptr->x2 = undo_end_x;
- block_setzen(t_ptr);
- block_delete(t_ptr, &t); /* Block ausschneiden und als Undotext */
- if (undo==BLK_PASTE)
- {
- undo_takes_text(&t);
- add_undo(BLK_CUT);
- }
- else
- {
- trash_takes_text(&t);
- add_undo(BLK_DEL);
- }
- t_ptr->moved++;
- }
- if (undo==BLK_CUT) /* Block mu₧ wieder eingefügt werden */
- {
- RINGP tp;
-
- t_ptr->xpos = undo_anf_x;
- tp = get_undo_text();
- block_einsetzen(t_ptr, tp);
- add_undo(BLK_PASTE);
- }
- if (undo==BLK_DEL) /* Text aus Papierkorb wieder einsetzten */
- {
- RINGP tp;
-
- t_ptr->xpos = undo_anf_x;
- tp = &(get_text(itrash)->text);
- block_einsetzen(t_ptr, tp);
- add_undo(BLK_PASTE_TRASH);
- }
- }
-
- VOID blk_right(TEXTP t_ptr, BOOLEAN onechar)
- {
- LINEP lauf;
- LONG y, ende;
- BOOLEAN t = t_ptr->loc_opt->tab;
-
- if (!t_ptr->block)
- return;
- lauf = t_ptr->p1;
- y = t_ptr->z1;
- ende = t_ptr->z2;
- if (y < ende)
- {
- WORD anz, i;
- UBYTE c, *str;
-
- if (t)
- {
- anz = 1;
- c = '\t';
- }
- else
- {
- anz = t_ptr->loc_opt->tabsize;
- c = ' ';
- }
- if (onechar)
- {
- anz = 1;
- c = ' ';
- }
- t_ptr->moved++;
- clr_undo();
- if (t_ptr->x1>0) t_ptr->x1 += anz;
- while (y<ende || t_ptr->x2>0)
- {
- if (lauf->len+anz>MAX_LINE_LEN)
- {
- inote(1, TOOLONG, MAX_LINE_LEN);
- break;
- }
- str = REALLOC(&lauf,0,anz);
- for (i=anz; (--i)>=0; )
- *str++ = c;
- if (y==t_ptr->z1)
- t_ptr->p1 = lauf;
- if (y==ende)
- {
- t_ptr->p2 = lauf;
- break;
- }
- NEXT(lauf);
- y++;
- }
- if (t_ptr->x2>0) t_ptr->x2 += anz;
- t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
- make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
- }
- }
-
- VOID blk_left(TEXTP t_ptr, BOOLEAN onechar)
- {
- LINEP lauf;
- LONG y, ende;
- BOOLEAN t = t_ptr->loc_opt->tab;
- WORD ts = t_ptr->loc_opt->tabsize;
-
- if (!t_ptr->block)
- return;
- if (!ist_mem_frei())
- return;
- lauf = t_ptr->p1;
- y = t_ptr->z1;
- ende = t_ptr->z2;
- if (y < ende)
- {
- WORD anz;
-
- if (t)
- anz = 1;
- else
- anz = ts;
- /*
- Rene, kommt noch!
- if (onechar)
- {
- anz = ts = 1;
- t = FALSE;
- }
- */
- t_ptr->moved++;
- clr_undo();
- if (tab_ok(lauf,t,ts))
- {
- if (t_ptr->x1 <= anz)
- t_ptr->x1 = 0;
- else
- t_ptr->x1 -= anz;
- }
- while (y < ende || t_ptr->x2 > 0)
- {
- if (tab_ok(lauf,t,ts))
- {
- REALLOC(&lauf, 0, -anz);
- if (y == t_ptr->z1)
- t_ptr->p1 = lauf;
- if (y == ende)
- t_ptr->p2 = lauf;
- }
- if (y == ende)
- break;
- NEXT(lauf);
- y++;
- }
- if (tab_ok(lauf,t,ts))
- {
- if (t_ptr->x2 <= anz)
- t_ptr->x2 = 0;
- else
- t_ptr->x2 -= anz;
- }
- t_ptr->cursor_line = get_line(&t_ptr->text, t_ptr->ypos);
- make_chg(t_ptr->link, POS_CHANGE, 0);
- make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
- }
- }
-
- /*-------------------------------------------------------------------*/
-
- VOID str_ch_uprlwr (UBYTE *line)
- {
- UBYTE stra[2],strb[2];
-
- stra[1] = strb[1] = EOS;
-
- while (*line != EOS)
- {
- stra[0] = *line;
- strb[0] = *line;
- str_upper(stra);
- str_lower(strb);
- if (stra[0] == *line)
- *line = strb[0];
- else
- *line = stra[0];
-
- line++;
- }
- }
-
- VOID strcap (UBYTE *line, SET wort_set)
- {
- UBYTE stra[2],strb[2];
-
- stra[1] = strb[1] = EOS;
- stra[0] = *line;
- if (setin(wort_set,stra[0]))
- {
- str_upper(stra);
- *line=stra[0];
- }
- line++;
- while (*line != EOS)
- {
- strb[0] = *(line-1);
- if (!setin(wort_set,strb[0]))
- {
- stra[0] = *line;
- if (setin(wort_set,stra[0]))
- {
- str_upper(stra);
- *line=stra[0];
- }
- }
- line++;
- }
- }
-
- VOID blk_upplow(TEXTP t_ptr, int type)
- {
- LINEP lauf;
- LONG y, ende;
-
- if (!t_ptr->block)
- return;
-
- lauf = t_ptr->p1;
- y = t_ptr->z1;
- ende = t_ptr->z2;
- if (y <= ende)
- {
- UBYTE *Tline, c;
-
- t_ptr->moved++;
- clr_undo();
- while (y < ende || t_ptr->x2 > 0)
- {
- if (y == t_ptr->z1)
- Tline = TEXT(lauf)+t_ptr->x1;
- else
- Tline = TEXT(lauf);
- if (y == ende)
- {
- c = *(TEXT(lauf)+t_ptr->x2);
- *(TEXT(lauf)+t_ptr->x2) = EOS; /* Zeile unterbrechen */
- }
- switch (type)
- {
- case BLK_UPPER:
- str_upper (Tline);
- break;
- case BLK_LOWER :
- str_lower (Tline);
- break;
- case BLK_CH_UPLO :
- str_ch_uprlwr (Tline);
- break;
- case BLK_CAPS :
- str_lower (Tline);
- strcap (Tline,t_ptr->loc_opt->wort_set);
- break;
- }
- if (y == ende)
- {
- *(TEXT(lauf)+t_ptr->x2) = c; /* Zeile restaurieren */
- break;
- }
- NEXT(lauf);
- y++;
- }
- t_ptr->moved++;
- make_chg(t_ptr->link, POS_CHANGE, 0);
- make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
- }
- }
-
- /*----------------------------------------------------------------*/
-
- LOCAL VOID block_demark(TEXTP t_ptr)
- {
- t_ptr->block = FALSE;
- t_ptr->cursor = TRUE;
- }
-
- LOCAL BOOLEAN tab_ok(LINEP a, BOOLEAN tab, WORD tabsize)
- {
- WORD anz;
- UBYTE *str;
-
- if (tab)
- {
- if (a->len==0) return(FALSE);
- str = TEXT(a);
- if (*str!='\t') return(FALSE);
- }
- else
- {
- anz = tabsize;
- if (a->len<anz) return(FALSE);
- str = TEXT(a);
- while ((--anz)>=0)
- {
- if (*str++!=' ') return(FALSE);
- }
- }
- return(TRUE);
- }
-
- LOCAL VOID block_setzen(TEXTP t_ptr)
- {
- if (t_ptr->p1 == t_ptr->p2 && t_ptr->x1 == t_ptr->x2)
- return;
-
- if (t_ptr->z1 > t_ptr->z2) /* Richtung falsch => tauschen */
- {
- LINEP col;
- LONG l;
- WORD i;
-
- t_ptr->block_dir ^= TRUE;
- i = t_ptr->x1;
- t_ptr->x1 = t_ptr->x2;
- t_ptr->x2 = i;
- col = t_ptr->p1;
- t_ptr->p1 = t_ptr->p2;
- t_ptr->p2 = col;
- l = t_ptr->z1;
- t_ptr->z1 = t_ptr->z2;
- t_ptr->z2 = l;
- }
- else if (t_ptr->z1 == t_ptr->z2 && t_ptr->x1 > t_ptr->x2)
- {
- WORD xw;
-
- t_ptr->block_dir ^= TRUE;
- xw = t_ptr->x1;
- t_ptr->x1 = t_ptr->x2;
- t_ptr->x2 = xw;
- }
- t_ptr->block = TRUE;
- t_ptr->cursor = FALSE;
- }
-
- LOCAL BOOLEAN block_delete(TEXTP t_ptr, RINGP t)
- {
- LINEP b_anf_col, b_end_col;
- LONG lines;
-
- b_anf_col = t_ptr->p1;
- b_end_col = t_ptr->p2;
- if (b_end_col->len-t_ptr->x2+t_ptr->x1>MAX_LINE_LEN)
- {
- inote(1, TOOLONG, MAX_LINE_LEN);
- return(FALSE);
- }
-
- /* Cursor an den Blockanfang bringen */
- t_ptr->ypos = t_ptr->z1;
- t_ptr->xpos = t_ptr->x1;
-
- undo_anf_y = t_ptr->z1;
- undo_anf_x = t_ptr->x1;
- undo_y = t_ptr->ypos; /* globale Merkvariable */
-
- lines = t_ptr->z2-t_ptr->z1+1;
- if (lines==1) /* ganz ohne Zeilenumbruch */
- {
- WORD len = t_ptr->x2-t_ptr->x1;
- LINEP b;
-
- init_textring(t);
- b = FIRST(t);
- INSERT(&b, 0, len, TEXT(b_anf_col)+t_ptr->x1);
- REALLOC(&b_anf_col, t_ptr->x1, -len);
- t_ptr->cursor_line = b_anf_col;
- }
- else
- {
- col_split(&b_end_col,t_ptr->x2);
- NEXT(b_end_col);
- col_split(&b_anf_col,t_ptr->x1);
-
- /* Block ausschneiden */
- FIRST(t) = b_anf_col->nachf;
- b_anf_col->nachf->vorg = &t->head;
- LAST(t) = b_end_col->vorg;
- b_end_col->vorg->nachf = &t->tail;
- t->lines = lines;
-
- /* Kette wieder schlie₧en */
- b_anf_col->nachf = b_end_col;
- b_end_col->vorg = b_anf_col;
- col_concate(&b_anf_col);
- t_ptr->cursor_line = b_anf_col;
- }
- if (lines==1)
- {
- make_chg(t_ptr->link,POS_CHANGE, 0);
- make_chg(t_ptr->link,LINE_CHANGE, undo_y);
- }
- else if (lines==2)
- {
- make_chg(t_ptr->link,POS_CHANGE, 0);
- make_chg(t_ptr->link,LINE_CHANGE, undo_y);
- make_chg(t_ptr->link,SCROLL_UP, undo_y+1);
- }
- else
- {
- make_chg(t_ptr->link,POS_CHANGE, 0);
- make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
- }
- t_ptr->block = FALSE;
- t_ptr->cursor = TRUE;
- t_ptr->text.lines -= (lines-1);
-
- return(TRUE);
- }
-
- VOID block_copy(TEXTP t_ptr, RINGP t)
- {
- LINEP a, lauf;
-
- init_textring(t);
- a = FIRST(t); /* erste Zeile */
- lauf = t_ptr->p1; /* Blockstart */
- if (lauf==t_ptr->p2) /* nur eine Zeile */
- {
- INSERT(&a, 0, t_ptr->x2-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
- a->info |= ABSATZ;
- }
- else
- {
- LINEP new, ende;
-
- /* erste Zeile teilweise */
- INSERT(&a, 0, lauf->len-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
- if (lauf->info&ABSATZ) a->info |= ABSATZ;
- else a->info &= (~ABSATZ);
- ende = t_ptr->p2;
- NEXT(lauf);
- NEXT(a); /* TAIL im neuen Text */
- while (lauf!=ende && ist_mem_frei())
- {
- new = new_col_w(TEXT(lauf), lauf->len);
- if (lauf->info&ABSATZ) new->info |= ABSATZ;
- col_insert(a->vorg,new);
- t->lines++;
- NEXT(lauf);
- }
- new = new_col_w(TEXT(lauf),t_ptr->x2); /* letzte Zeile teilweise */
- new->info |= ABSATZ;
- col_insert(a->vorg,new);
- t->lines++;
- }
- }
-
- /* Der Cursor von t_ptr steht anschlie₧end hinter der Einfügung */
- LOCAL BOOLEAN block_einsetzen(TEXTP t_ptr, RINGP in)
- {
- RING t;
- LINEP a,b,
- col = t_ptr->cursor_line;
- LONG len;
-
- a = FIRST(in);
- b = LAST(in);
- if ((a!=b &&
- (t_ptr->xpos+a->len>MAX_LINE_LEN ||
- b->len+(col->len-t_ptr->xpos)>MAX_LINE_LEN)) ||
- (a==b &&
- col->len+a->len>MAX_LINE_LEN))
- {
- inote(1, TOOLONG, MAX_LINE_LEN);
- return(FALSE);
- }
-
- init_textring(&t);
- doppeln(in, &t);
- a = FIRST(&t);
- b = LAST(&t);
-
- if (t.lines==1) /* Ganz ohne Zeilenveränderung */
- make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
- else if(t.lines==2) /* Einen Zeilenumbruch */
- {
- make_chg(t_ptr->link,SCROLL_DOWN,t_ptr->ypos+1);
- make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
- make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos+1);
- }
- else
- {
- make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->ypos);
- }
-
- len = t.lines-1;
- t_ptr->text.lines += len;
-
- undo_anf_y = t_ptr->ypos;
- undo_anf_x = t_ptr->xpos;
- undo_end_y = undo_anf_y+len;
- undo_end_x = b->len;
- undo_y = t_ptr->ypos; /* globale Merkvariable */
- if (len==0)
- {
- INSERT(&col, t_ptr->xpos, a->len, TEXT(a));
- undo_end_x += t_ptr->xpos;
- kill_textring(&t);
- }
- else
- {
- col_split(&col,t_ptr->xpos); /* Textzeile splitten */
-
- col->nachf->vorg = b; /* Block einfügen unten */
- b->nachf = col->nachf;
- col_concate(&b); /* Untere letzte Zeile */
-
- col->nachf = a; /* Block einfügen oben */
- a->vorg = col;
- col_concate(&col);
- }
- /* Cursor hinter Einfügung */
- t_ptr->cursor_line = get_line(&t_ptr->text,undo_end_y);
- t_ptr->ypos = undo_end_y;
- t_ptr->xpos = undo_end_x;
- t_ptr->moved++;
- make_chg(t_ptr->link, POS_CHANGE, 0);
- return(TRUE);
- }
-
- VOID block_info(TEXTP t_ptr)
- {
- UBYTE str[30];
- RING t;
-
- block_copy(t_ptr,&t);
- if (t_ptr->x1 == 0 && t_ptr->x2 == 0)
- t.lines -= 1;
-
- make_shortpath(t_ptr->filename, str, 30);
- fill_ptext(blockinfo, BLONAME, str); /* Name mit Pfad */
-
- ltoa(textring_bytes(&t, t_ptr->ending), str, 10);
- fill_ptext(blockinfo, BLOGROSS, str); /* Grö₧e in Bytes */
-
- ltoa((&t)->lines, str, 10);
- fill_ptext(blockinfo, BLOZEILE, str);
-
- Arrow_mouse();
- HndlDial(blockinfo, 0, FALSE, NULL, NULL);
- Last_mouse();
-
- kill_textring(&t);
- }
-